package com.rtu.web;

import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSON;
import com.rtu.dao.IProjectFieldDao;
import com.rtu.dao.IProjectRtuDao;
import com.rtu.domain.ProjectField;
import com.rtu.domain.ProjectPassGateway;
import com.rtu.domain.ProjectRtuGatherData;
import com.rtu.domain.WPProject;
import com.rtu.dto.ProjectRtuDto;
import com.rtu.dto.QueryPassGatewayValueDto;
import com.rtu.dto.QueryProjectDto;
import com.rtu.dto.QueryProjectReportDto;
import com.rtu.dto.SubmitProject;
import com.rtu.dto.SubmitUpdateProject;
import com.rtu.dto.UpdateProjectDto;
import com.rtu.dto.response.ApiResponse;
import com.rtu.enums.Code;
import com.rtu.service.IProjectService;
import com.rtu.utils.DateUtil;
import com.rtu.utils.JDBCUtil;
import com.rtu.utils.ResultSetMapper;

@Controller
@RequestMapping("/project")
@SuppressWarnings({"rawtypes","unchecked"})
public class ProjectController {
	
	private static final Logger logger = LoggerFactory.getLogger(ProjectController.class);

	@Resource
	private IProjectService projectService;
	@Resource
	private IProjectRtuDao projectRtuDao;
	@Resource
	private IProjectFieldDao projectFieldDao;
	
    @RequestMapping("/getPageList")
    @ResponseBody
    public ApiResponse getList(QueryProjectDto dto){
        ApiResponse apiResponse;
        try {
            if (dto.getPage() == null) {
                dto.setPage(1);
            }
            if (dto.getPageRowCount() == null) {
                dto.setPageRowCount(50);
            }
            Map map = projectService.query(dto);
            apiResponse = ApiResponse.create(true, Code.SUCCESS,map);
        }catch (Exception e){
            logger.error("getList",e);
            apiResponse = ApiResponse.create(false,e.getMessage(), Code.COMMON_SERVER_ERROR.code,null);
        }
        return apiResponse;
    }
    
    
	@RequestMapping("/goUpdateProject")
    @ResponseBody
    public ApiResponse goUpdateProject(UpdateProjectDto dto){
    	ApiResponse apiResponse;
        try {
            Map map = projectService.goUpdateProject(dto);
            List<String> tableFieldName = new ArrayList<String>();
            tableFieldName.add("ch");
            tableFieldName.add("va");
            tableFieldName.add("create_time");
            map.put("mappingField", tableFieldName);
            if(null != dto.getProjectId()) {
                List<ProjectField> projectField = this.projectFieldDao.query(dto.getProjectId());
                map.put("projectField", projectField);
            }
            apiResponse = ApiResponse.create(true, Code.SUCCESS,map);
        }catch (Exception e){
            logger.error("goUpdateProject",e);
            apiResponse = ApiResponse.create(false,e.getMessage(), Code.COMMON_SERVER_ERROR.code,null);
        }
    	return apiResponse;
    }
    
    @RequestMapping("/submitUpdateProject")
    @ResponseBody
    public ApiResponse submitUpdateProject(SubmitProject submitProject){
    	SubmitUpdateProject dto = JSON.parseObject(submitProject.getParamStr(), SubmitUpdateProject.class);
    	ApiResponse apiResponse;
        try {
            projectService.submitUpdateProject(dto);
            apiResponse = ApiResponse.create(true, Code.SUCCESS,null);
        }catch (Exception e){
            logger.error("goUpdateProject",e);
            apiResponse = ApiResponse.create(false,e.getMessage(), Code.COMMON_SERVER_ERROR.code,null);
        }
    	return apiResponse;
    }
    
    @RequestMapping("/createProject")
    @ResponseBody
    public ApiResponse createProject(SubmitProject submitProject){
    	SubmitUpdateProject dto = JSON.parseObject(submitProject.getParamStr(), SubmitUpdateProject.class);
    	ApiResponse apiResponse;
    	JDBCUtil jdbcUtil = null;
        try {
            int projectId = projectService.createProject(dto);
            jdbcUtil = new JDBCUtil(dto.getProject().getJdbcDriver(), dto.getProject().getJdbcUrl(),dto.getProject().getJdbcUserName(), dto.getProject().getJdbcPassword());
            String listSql = String.format(dto.getProject().getGatherDataSql(), ">0");
            ResultSet resultSet = jdbcUtil.excuteQueryResultSet(listSql + "  LIMIT 0,100", null);
            ResultSetMapper<ProjectRtuGatherData> resultSetMapper = new ResultSetMapper<ProjectRtuGatherData>(); 
            List<ProjectRtuGatherData> rtuList = resultSetMapper.mapRersultSetToObject(resultSet, ProjectRtuGatherData.class);
            if(null != rtuList && rtuList.size() > 0) {
            	for(ProjectRtuGatherData d : rtuList) {
            		d.setProjectId(projectId);
            	}
            	projectRtuDao.batchInsert(rtuList);
            }
            apiResponse = ApiResponse.create(true, Code.SUCCESS,null);
        }catch (Exception e){
            logger.error("goUpdateProject",e);
            apiResponse = ApiResponse.create(false,e.getMessage(), Code.COMMON_SERVER_ERROR.code,null);
        }finally {
        	if(null != jdbcUtil) {
        		jdbcUtil.closeAll();
        	}
        }
    	return apiResponse;
    }
    
    @RequestMapping("/uploadImage")
    @ResponseBody
    public ApiResponse uploadImage(WPProject dto){
    	ApiResponse apiResponse;
        try {
            projectService.updateImage(dto);
            apiResponse = ApiResponse.create(true, Code.SUCCESS,null);
        }catch (Exception e){
            logger.error("goUpdateProject",e);
            apiResponse = ApiResponse.create(false,e.getMessage(), Code.COMMON_SERVER_ERROR.code,null);
        }
    	return apiResponse;
    }
    
    @RequestMapping("/getProject")
    @ResponseBody
    public ApiResponse getProject(QueryProjectReportDto dto){
        ApiResponse apiResponse;
        try {
            if (dto == null || dto.getProjectId() == null || dto.getProjectId() == 0) {
                apiResponse = ApiResponse.create(false,null, Code.BAD_PARAMS.code,null);
                return apiResponse;
            }
            Map map = projectService.queryProjectById(dto.getProjectId());
            if (map == null || map.get("project") == null) {
                apiResponse = ApiResponse.create(false,null, Code.NO_PROJECT.code,null);
                return apiResponse;
            }
            apiResponse = ApiResponse.create(true, Code.SUCCESS,map);
        }catch (Exception e){
            logger.error("getProject",e);
            apiResponse = ApiResponse.create(false,e.getMessage(),Code.COMMON_SERVER_ERROR.code,null);
        }
        return apiResponse;
    }
    
	@RequestMapping("/getList")
    @ResponseBody
    public ApiResponse getList(QueryProjectReportDto dto){
        ApiResponse apiResponse;
        JDBCUtil jdbcUtil = null;
        try {
            if (dto == null || null == dto.getProjectId()) {
                apiResponse = ApiResponse.create(false,null, Code.BAD_PARAMS.code,null);
                return apiResponse;
            }
            UpdateProjectDto queryParam = new UpdateProjectDto();
            queryParam.setProjectId(dto.getProjectId());
            Map map = projectService.goUpdateProject(queryParam);
            if (map == null || map.get("project") == null) {
                apiResponse = ApiResponse.create(false,null, Code.NO_PROJECT.code,null);
                return apiResponse;
            }
            WPProject project = (WPProject)map.get("project");
            String sql = "select ch, va, date_format(create_time, '%Y-%m-%d %H:%i:%S') createTime from tb_rtu_data_gather";
            String condition = " where project_id = " + dto.getProjectId();
            Map result = new HashMap();
    		if(StringUtils.isNotBlank(dto.getCh())) {
    			condition = condition + " and ch = "+ dto.getCh();
    		}
    		if(StringUtils.isNotBlank(dto.getBeginTime())) {
    			condition = condition + " and create_time >='" + dto.getBeginTime() + "'";
    		}
    		if(StringUtils.isNotBlank(dto.getEndTime())) {
    			condition = condition + " and create_time <='" + dto.getEndTime() + "'";
    		}
            sql = sql +  " " + condition + "  order by create_time desc limit " + dto.getOffset() * dto.getRows() + " , " + dto.getRows();
            jdbcUtil = new JDBCUtil(project.getJdbcDriver(), project.getJdbcUrl(),project.getJdbcUserName(), project.getJdbcPassword());
            List<Object> listResult = jdbcUtil.excuteQuery(sql, null);
            result.put("reportData", listResult);
            result.put("passGateway", map.get("passGateway"));
            
            List<ProjectField> projectField = this.projectFieldDao.query(dto.getProjectId());
            result.put("rowHead", projectField);
            apiResponse = ApiResponse.create(true, Code.SUCCESS,result);
        }catch (Exception e){
            logger.error("getList",e);
            apiResponse = ApiResponse.create(false,e.getMessage(),Code.COMMON_SERVER_ERROR.code,null);
        }finally {
        	if(null != jdbcUtil) {
        		jdbcUtil.closeAll();
        	}
        }
        return apiResponse;
    }
    
    @RequestMapping("/getPassGatewayValue")
    @ResponseBody
    public ApiResponse getPassGatewayValue(QueryPassGatewayValueDto dto){
    	ApiResponse apiResponse;
    	JDBCUtil jdbcUtil = null;
        try {
        	jdbcUtil = new JDBCUtil(dto.getJdbcDriver(), dto.getJdbcUrl(),dto.getJdbcUserName(), dto.getJdbcPassword());
            String sql = "select DISTINCT  " + dto.getFieldName() + " from" + " " + dto.getTableName();
            List<Object> listResult = jdbcUtil.excuteQuery(sql, null);
            apiResponse = ApiResponse.create(true, Code.SUCCESS,listResult);
        }catch (Exception e){
            logger.error("goUpdateProject",e);
            apiResponse = ApiResponse.create(false,e.getMessage(), Code.COMMON_SERVER_ERROR.code,null);
        }finally {
        	if(null != jdbcUtil) {
        		jdbcUtil.closeAll();
        	}
        }
    	return apiResponse;
    }

    @RequestMapping("/getRecentData")
    @ResponseBody
    public ApiResponse getRecentData(QueryProjectReportDto dto){
        ApiResponse apiResponse;
        try {
            if (dto == null) {
                apiResponse = ApiResponse.create(false,null, Code.BAD_PARAMS.code,null);
                return apiResponse;
            }
            UpdateProjectDto queryParam = new UpdateProjectDto();
            queryParam.setProjectId(dto.getProjectId());
            Map map = projectService.goUpdateProject(queryParam);
            if (map == null || map.get("project") == null) {
                apiResponse = ApiResponse.create(false,null, Code.NO_PROJECT.code,null);
                return apiResponse;
            }
            Map result = new HashMap();
            List<ProjectPassGateway> gatewayList = projectService.queryProjectPassGateway(dto.getProjectId());
            for(ProjectPassGateway g:gatewayList) {
            	QueryProjectReportDto paramDto = new QueryProjectReportDto();
            	paramDto.setProjectId(dto.getProjectId());
            	paramDto.setCh(String.valueOf(g.getGatewayValue()));
            	ProjectRtuDto rtu = projectRtuDao.queryRecent(paramDto);
                result.put("list" + g.getGatewayValue(), rtu);
            }
            List<ProjectField> projectField = this.projectFieldDao.query(dto.getProjectId());
            result.put("rowHead", projectField);
            result.put("passGateway", map.get("passGateway"));
            apiResponse = ApiResponse.create(true, Code.SUCCESS,result);
        }catch (Exception e){
            logger.error("getRecentData",e);
            apiResponse = ApiResponse.create(false,e.getMessage(),Code.COMMON_SERVER_ERROR.code,null);
        }
        return apiResponse;
    }
    
    @RequestMapping("/getReportData")
    @ResponseBody
    public ApiResponse getReportData(QueryProjectReportDto dto){
        ApiResponse apiResponse;
        JDBCUtil jdbcUtil = null;
        try {
            if (dto == null) {
                apiResponse = ApiResponse.create(false,null, Code.BAD_PARAMS.code,null);
                return apiResponse;
            }

            UpdateProjectDto queryParam = new UpdateProjectDto();
            queryParam.setProjectId(dto.getProjectId());
            Map map = projectService.goUpdateProject(queryParam);
            if (map == null || map.get("project") == null) {
                apiResponse = ApiResponse.create(false,null, Code.NO_PROJECT.code,null);
                return apiResponse;
            }
            WPProject project = (WPProject)map.get("project");
            String sql = "select ch, va, date_format(create_time, '%Y-%m-%d %H:%i:%S') createTime from tb_rtu_data_gather";
            String condition = " where 1=1 ";
            Map result = new HashMap();
            List<ProjectPassGateway> gatewayList = projectService.queryProjectPassGateway(dto.getProjectId());
            Date date1 = DateUtil.parseDate(dto.getBeginTime());
            Date date2 = DateUtil.parseDate(dto.getEndTime());
            int count = DateUtil.getBetweenDays(date1,date2).intValue();
            for(ProjectPassGateway g:gatewayList) {
                condition = " where 1=1 ";
                condition = condition + " and ch = "+ g.getGatewayValue();
           		if(count == 1) {
           			sql = "select ch, va, date_format(create_time, '%Y-%m-%d %H:%i:%S') createTime from tb_rtu_data_gather";
            		if(StringUtils.isNotBlank(dto.getBeginTime())) {
            			condition = condition + " and create_time >='" + dto.getBeginTime() + "'";
            		}
            		if(StringUtils.isNotBlank(dto.getEndTime())) {
            			condition = condition + " and create_time <'" + dto.getEndTime() + "'";
            		}
            		condition = condition + " GROUP BY HOUR(create_time) ";
        		} else if(count == 7) {
        			sql = "select va, date_format(min(create_time), '%Y-%m-%d %H:%i:%S') createTime  from tb_rtu_data_gather";
            		if(StringUtils.isNotBlank(dto.getBeginTime())) {
            			condition = condition + " and create_time >='" + dto.getBeginTime() + "'";
            		}
            		if(StringUtils.isNotBlank(dto.getEndTime())) {
            			condition = condition + " and create_time <'" + dto.getEndTime() + "'";
            		}
        			condition = condition + " GROUP BY DATE_FORMAT(create_time,'%Y-%m-%d %H') ";
        		} else if (count <=31 ) {
        			sql = "select ch, va, date_format(min(create_time), '%Y-%m-%d %H:%i:%S') createTime  from tb_rtu_data_gather";
            		if(StringUtils.isNotBlank(dto.getBeginTime())) {
            			condition = condition + " and create_time >='" + dto.getBeginTime() + "'";
            		}
            		if(StringUtils.isNotBlank(dto.getEndTime())) {
            			condition = condition + " and create_time <'" + dto.getEndTime() + "'";
            		}
        			condition = condition + " GROUP BY DATE_FORMAT(create_time,'%Y-%m-%d')";
        		}else {
        			sql = "select ch, va, date_format(min(create_time), '%Y-%m-%d %H:%i:%S') createTime  from tb_rtu_data_gather";
        			List<String> dateList = DateUtil.getMonday(date1,date2);
        			String dateListStr = "";
        			for(String d : dateList) {
        				if(StringUtils.isNotBlank(dateListStr)) {
        					dateListStr = dateListStr + ",'" + d + "'";
        				} else {
        					dateListStr = "('" + d +"'";
        				}
        			}
        			if(StringUtils.isNotBlank(dateListStr)) {
        				dateListStr = dateListStr + ")";
        				condition = condition + " and DATE_FORMAT(create_time,'%Y-%m-%d')" + " in " + dateListStr;
        				condition = condition + " GROUP BY DATE_FORMAT(create_time,'%Y-%m-%d')";
        			}
        		}
           		
                sql = sql + " " + condition + "  order by create_time asc";
                jdbcUtil = new JDBCUtil(project.getJdbcDriver(), project.getJdbcUrl(),project.getJdbcUserName(), project.getJdbcPassword());
                List<Object> listResult = jdbcUtil.excuteQuery(sql, null);
                if(StringUtils.isNotBlank(dto.getCh())) {
                	if(g.getGatewayValue() == Integer.valueOf(dto.getCh())) {
                		result.put("list" + g.getGatewayValue(), listResult);
                	}
                } else {
                	result.put("list" + g.getGatewayValue(), listResult);
                }
            }
            List<ProjectField> projectField = this.projectFieldDao.query(dto.getProjectId());
            result.put("rowHead", projectField);
            result.put("passGateway", map.get("passGateway"));
            apiResponse = ApiResponse.create(true, Code.SUCCESS,result);
        }catch (Exception e){
            logger.error("getReportData",e);
            apiResponse = ApiResponse.create(false,e.getMessage(),Code.COMMON_SERVER_ERROR.code,null);
        }finally {
        	if(null != jdbcUtil) {
        		jdbcUtil.closeAll();
        	}
        }
        return apiResponse;
    }
}
